package com.example.luyao.myapplication;

import java.util.ArrayList;
import java.util.List;

import org.webrtc.EglBase;
import org.webrtc.MediaStream;
import org.webrtc.SurfaceViewRenderer;
import org.webrtc.VideoFrame;
import org.webrtc.RendererCommon.ScalingType;
import org.webrtc.VideoSink;
import org.webrtc.VideoTrack;

import com.reconova.webrtcclient.PercentFrameLayout;

import com.example.webrtcclient.WebRtcClient;
import com.example.webrtcclient.PeerConnectionParameters;

import android.app.Activity;
import android.net.ConnectivityManager;
import android.net.NetworkInfo;
import android.os.Bundle;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.IntentFilter;
import android.graphics.PixelFormat;
import android.util.Log;
import android.view.KeyEvent;
import android.view.View;
import android.view.WindowManager;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;

public class MainActivity extends Activity  implements WebRtcClient.RtcListener {
    private final static String TAG = MainActivity.class.getCanonicalName();
    private SurfaceViewRenderer remoteRender;
    private PercentFrameLayout mView = null;
    private static final int REMOTE_X = 0;
    private static final int REMOTE_Y = 0;
    private static final int REMOTE_WIDTH = 100;
    private static final int REMOTE_HEIGHT = 100;
    private EglBase rootEglBase;
    ScalingType scalingType = ScalingType.SCALE_ASPECT_FILL;
    private boolean mIsPlayingVideo;

    private EditText mEdtAddr;
	private EditText mEditDevID;
    private TextView mStateInfo;

    private Button mBtnLogin;
    private Button mBtnLogout;

    private Button mBtnResolutionLow;
    private Button mBtnResolutionMid;
    private Button mBtnResolutionHigh;

    private Button mBtnSendStartVideo;
    private Button mBtnSendStopVideo;


	private String mDevID = "";
	private WebRtcClient webRtcClient;
    private final ProxyVideoSink remoteProxyRenderer = new ProxyVideoSink();
    private final List<VideoSink> remoteSinks = new ArrayList<>();

    private static class ProxyVideoSink implements VideoSink {
        private VideoSink target;

        @Override
        synchronized public void onFrame(VideoFrame frame) {
            if (target == null) {
                Log.e(TAG, "Dropping frame in proxy because target is null.");
                return;
            }

            target.onFrame(frame);
        }

        synchronized public void setTarget(VideoSink target) {
            this.target = target;
        }
    }

    protected void toast(final String msg) {
        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Toast.makeText(getApplicationContext(), msg, Toast.LENGTH_SHORT).show();
            }
        });
    }

	public void alert(String sTitle, String sMsg) {
		AlertDialog.Builder builder = new AlertDialog.Builder(this);
		builder.setTitle(sTitle);
		builder.setMessage(sMsg);
		builder.setPositiveButton("OK", null);
		builder.show();
	}

	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.activity_main);
		getWindow().setFormat(PixelFormat.TRANSLUCENT);  
		getWindow().setFlags(WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON,
				WindowManager.LayoutParams.FLAG_KEEP_SCREEN_ON);
		
		mStateInfo = findViewById(R.id.textViewInfo);
		mEdtAddr = findViewById(R.id.editAddr);
		mEditDevID = findViewById(R.id.editDevID);

        mBtnLogin = findViewById(R.id.btnLogin);
        mBtnLogin.setOnClickListener(mOnClick);
		mBtnLogout = findViewById(R.id.btnLogout);
		mBtnLogout.setOnClickListener(mOnClick);

		mBtnResolutionLow = findViewById(R.id.btnResolutionLow);
		mBtnResolutionLow.setOnClickListener(mOnClick);
		mBtnResolutionMid = findViewById(R.id.btnResolutionMid);
		mBtnResolutionMid.setOnClickListener(mOnClick);
		mBtnResolutionHigh = findViewById(R.id.btnResolutionHigh);
		mBtnResolutionHigh.setOnClickListener(mOnClick);

		mBtnSendStartVideo = findViewById(R.id.btnSendStartVideo);
		mBtnSendStartVideo.setOnClickListener(mOnClick);
		mBtnSendStopVideo = findViewById(R.id.btnSendStopVideo);
		mBtnSendStopVideo.setOnClickListener(mOnClick);

		registerReceiver();

        remoteRender = findViewById(R.id.remote_video_view);
        rootEglBase = EglBase.create();
        remoteRender.init(rootEglBase.getEglBaseContext(), null);

        PeerConnectionParameters params = new PeerConnectionParameters(
                false, false, 0, 0, 15,
                1, "H264", true, 1,
                "opus", true, true,
                true, true);
        Log.e(TAG, "Initialize WebRTC");
        webRtcClient = new WebRtcClient(getApplicationContext(), rootEglBase, params);

        //remoteRender.setLayoutParams(new LinearLayout.LayoutParams(320, 240));
        remoteRender.setScalingType(scalingType);
        remoteRender.setMirror(false);
        remoteRender.requestLayout();
        mView = findViewById(R.id.remote_video_layout);
        remoteRender.setVisibility(View.VISIBLE);

        remoteProxyRenderer.setTarget(remoteRender);
        remoteSinks.add(remoteProxyRenderer);

        updateVideoView();
	}

    private void updateVideoView() {
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                mView.setPosition(REMOTE_X, REMOTE_Y, REMOTE_WIDTH, REMOTE_HEIGHT);
                remoteRender.setScalingType(scalingType);
                remoteRender.setMirror(false);
                remoteRender.requestLayout();
            }
        });
    }

    private void liveSart() {
        Log.e(TAG, "liveSart");
        webRtcClient.startWebrtc(mEditDevID.getText().toString());
    }

    private void liveStop() {
        Log.e(TAG, "liveStop 0");
        webRtcClient.stopWebrtc();
    }

	private void liveInit(String serverAddress, String peerName) {
        String[] host_port = serverAddress.split(":");
        String ip;
        String port;
        if(host_port.length == 2) {
            ip = host_port[0];
            port = host_port[1];
        } else {
            Log.e(TAG, "server address format error");
            return;
        }
        String socketAddress = "ws://" + ip + ":" + port + "/";
        Log.e(TAG, "socketAddress " + socketAddress + " peerName " + peerName);
        webRtcClient.init(this, socketAddress, ip, peerName);
	}

    private void changeDisplaySize(float width, float height) {
        if (remoteRender == null) return;
        float ratio = height / width;
        int h = (int) (ratio * remoteRender.getWidth());
        remoteRender.setLayoutParams(new LinearLayout.LayoutParams(remoteRender.getWidth(), h));
        updateVideoView();
    }

    private void registerReceiver() {
        // 网络状态广播,在断网时候自动销毁p2p相关数据。
        IntentFilter intentFilter = new IntentFilter();
        intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
        registerReceiver(connectionReceiver, intentFilter);
    }

    public static boolean isConnected(Context context) {
        ConnectivityManager connectMgr = (ConnectivityManager) context
                .getSystemService(Activity.CONNECTIVITY_SERVICE);
        NetworkInfo mobNetInfo = connectMgr
                .getNetworkInfo(ConnectivityManager.TYPE_MOBILE);
        NetworkInfo wifiNetInfo = connectMgr
                .getNetworkInfo(ConnectivityManager.TYPE_WIFI);

        return mobNetInfo.isConnected() || wifiNetInfo.isConnected();
    }

    private BroadcastReceiver connectionReceiver = new BroadcastReceiver() {
            @Override
            public void onReceive(Context context, Intent intent) {
                if (!isConnected(getApplicationContext())) {
                    // 断网处理，清空直播资源。
                    liveStop();
                    toast("连接网络失败,请检查网络连接!");
                }
            }
	};

    public void onDestroy() {
        webRtcClient.unInit();
        if (remoteRender != null) {
            remoteRender.release();
            remoteRender = null;
        }
        unregisterReceiver(connectionReceiver);
        remoteProxyRenderer.setTarget(null);
        super.onDestroy();
    }

    public boolean onKeyUp(int keyCode, KeyEvent event) {
        if (keyCode == KeyEvent.KEYCODE_BACK && event.getRepeatCount() == 0) {
            showExitDialog();
            return true;
        }
        return super.onKeyUp(keyCode, event);
    }

    public void showExitDialog() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Confirm");
        builder.setMessage("Are you sure to exit?");
        builder.setPositiveButton("YES", mDlgClick);
        builder.setNegativeButton("NO", mDlgClick);
        builder.show();
    }

    private DialogInterface.OnClickListener mDlgClick = new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int which) {
                if (which == AlertDialog.BUTTON_POSITIVE) {
                    android.os.Process.killProcess(android.os.Process.myPid());
                }
            }
	};

    private View.OnClickListener mOnClick = new View.OnClickListener() {
            public void onClick(View args0) {
                Log.e(TAG, getResources().getResourceEntryName(args0.getId()));
                switch (args0.getId()) {
                    case R.id.btnLogin:
                        if (webRtcClient.isLogined()) {
                            toast("您已经登录了!");
                        } else {
                            mDevID = mEditDevID.getText().toString();
                            liveInit(mEdtAddr.getText().toString(), mDevID);
                        }
                        updateUI();
                        break;

                    case R.id.btnLogout:
                        if (alertLoginUnSuccess()) {
                            return;
                        }
                        liveStop();
                        webRtcClient.unInit();
                        updateUI();
                        break;

                    case R.id.btnSendStartVideo:
                        if (alertLoginUnSuccess()) {
                            return;
                        }
                        liveSart();
                        break;

                    case R.id.btnSendStopVideo:
                        if (alertIfUnConnected()) {
                            return;
                        }
                        mIsPlayingVideo = false;
                        toast("直播已关闭");
                        liveStop();
                        break;

                case R.id.btnResolutionLow:
                    if (alertIfUnConnected()) {
                        return;
                    }
                    changeDisplaySize(320, 240);
                    break;
                case R.id.btnResolutionMid:
                    if (alertIfUnConnected()) {
                        return;
                    }
                    changeDisplaySize(640, 480);
                    break;
                case R.id.btnResolutionHigh:
                    changeDisplaySize(1280, 720);
                    break;
                default:
                    break;
                }
            }
	};

    private boolean alertLoginUnSuccess() {
        if (!webRtcClient.isLogined()) {
            alert("尚未登陆成功", "未登陆成功,请检查网络连接!");
            return true;
        } else {
            return false;
        }
    }

    private boolean alertIfUnConnected() {
        if (!webRtcClient.isConnected()) {
            toast("p2p尚未连接成功！");
            return true;
        } else {
            return false;
        }
    }


    private void updateUI() {
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                if (!webRtcClient.isLogined()) {
                    mStateInfo.setText("尚未登录服务器");
                } else {
                    if (webRtcClient.isConnected()) {
                        mStateInfo.setText("p2p已连接");
                    } else {
                        mStateInfo.setText("p2p未连接");
                    }
                }            }
        });
    }

    // implement WebRtcClient.RtcListener
    @Override
    public void onStatusChanged(String newStatus) {
		//toast(newStatus);
    }

    @Override
    public void onAddRemoteStream(MediaStream remoteStream) {
        VideoTrack remoteVideoTrack = remoteStream.videoTracks.get(0);
        remoteVideoTrack.setEnabled(true);
        remoteVideoTrack.addSink(remoteSinks.get(0));
        updateVideoView();
    }

    @Override
    public void onRemoveRemoteStream() {}

    @Override
    public void onPeerLeave(){
        MainActivity.this.runOnUiThread(new Runnable() {
            public void run() {
                /*
                AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
                builder.setMessage("视频已播放完或连接已断开");
                builder.setTitle("提示");
                builder.setPositiveButton("确认", new DialogInterface.OnClickListener() {
                    @Override
                    public void onClick(DialogInterface dialog, int id) {
                        dialog.cancel();
                        //android.os.Process.killProcess(android.os.Process.myPid());
                        //restart(getApplicationContext(), 500);
                    }
                });
                builder.create().show();
                */
                toast("视频已播放完或文件下载完成");
            }
        });
        mIsPlayingVideo = false;
        liveStop();
        updateVideoView();
    }
}
